﻿//-----------------------------------------------------------------------
// <copyright file="IoC.cs" company="deixei.com">
//     Copyright (c) deixei.com. All rights reserved.
// </copyright>
// <author>Marcio Parente</author>
//---------------------------------------------------------------------
namespace Deixei.Infrastructure
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Web.Mvc;

    /// <summary>
    /// Inversion of Control
    /// </summary>
    public partial class IoC
    {
        /// <summary>
        /// Resolver container
        /// </summary>
        private static IDependencyResolver resolver;

        /// <summary>
        /// Initializes with Inversion of Control factory.
        /// </summary>
        /// <param name="factory">The factory.</param>
        /// <exception cref="System.ArgumentNullException">Argument Null Exception</exception>
        public static void InitializeWith(IDependencyResolverFactory factory)
        {
            if (factory == null)
            {
                throw new ArgumentNullException("factory");
            }

            resolver = factory.CreateInstance();
        }

        /// <summary>
        /// Registers the specified instance.
        /// </summary>
        /// <typeparam name="T">An object.</typeparam>
        /// <param name="instance">The instance of an object.</param>
        /// <exception cref="System.ArgumentNullException">Argument Null Exception</exception>
        public static void Register<T>(T instance)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            resolver.Register(instance);
        }


        /// <summary>
        /// Injects the specified existing.
        /// </summary>
        /// <typeparam name="T">An object.</typeparam>
        /// <param name="existing">The existing.</param>
        /// <exception cref="System.ArgumentNullException">Argument Null Exception</exception>
        public static void Inject<T>(T existing)
        {
            if (existing == null)
            {
                throw new ArgumentNullException("existing");
            }

            resolver.Inject(existing);
        }

        /// <summary>
        /// Resolves the specified type.
        /// </summary>
        /// <typeparam name="T">An object.</typeparam>
        /// <param name="type">The type.</param>
        /// <returns>Object of type T</returns>
        /// <exception cref="System.ArgumentNullException">Argument Null Exception</exception>
        public static T Resolve<T>(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            return resolver.Resolve<T>(type);
        }

        /// <summary>
        /// Resolves the specified type.
        /// </summary>
        /// <typeparam name="T">An object.</typeparam>
        /// <param name="type">The type.</param>
        /// <param name="name">The name.</param>
        /// <returns>Object of type T</returns>
        /// <exception cref="System.ArgumentNullException">Argument Null Exception</exception>
        public static T Resolve<T>(Type type, string name)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (name == null)
            {
                throw new ArgumentNullException("name");
            }

            return resolver.Resolve<T>(type, name);
        }

        /// <summary>
        /// Resolves this instance.
        /// </summary>
        /// <typeparam name="T">An object.</typeparam>
        /// <returns>Object of type T</returns>
        public static T Resolve<T>()
        {
            return resolver.Resolve<T>();
        }

        /// <summary>
        /// Resolves the specified name.
        /// </summary>
        /// <typeparam name="T">An object.</typeparam>
        /// <param name="name">The name.</param>
        /// <returns>Object of type T</returns>
        /// <exception cref="System.ArgumentNullException">Argument Null Exception</exception>
        public static T Resolve<T>(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            return resolver.Resolve<T>(name);
        }

        /// <summary>
        /// Resolves all.
        /// </summary>
        /// <typeparam name="T">An object.</typeparam>
        /// <returns>Enumerable of an object</returns>
        public static IEnumerable<T> ResolveAll<T>()
        {
            return resolver.ResolveAll<T>();
        }
    }
}
